home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / comm / bbs / citsrc6K05.lha / sysdep2.c < prev    next >
C/C++ Source or Header  |  1996-10-23  |  46KB  |  1,845 lines

  1. #include "dos.h"
  2. #include "stdio.h"
  3. #include "ctdl.h"
  4. #include "string.h"
  5. #include "stdarg.h"
  6. #include "clib/dos_protos.h"
  7. #include "minrexx.h"
  8.  
  9. char *SysVers            = SYSDEP_NAME ;
  10.  
  11. char ARexx_Name[20];
  12. int  SystemPort          = 0;
  13. #define CITADEL_REQUIRED_STACK  8192L
  14. #ifdef CTDL_BACKGROUND
  15. long _stack              = CITADEL_REQUIRED_STACK;
  16. char *_procname          = "CTDL";
  17. long _priority           = 0;
  18. long _BackGroundIO       = 1;
  19. extern BPTR _Backstdout;
  20. #endif
  21.  
  22. int  iconify_window      = FALSE;   /* we are not iconified so printf uses
  23.                                        crash.sys for output in startup     */
  24.  
  25.  
  26.  
  27. /* CTDL EXTERNS */
  28. extern CONFIG cfg;
  29. extern char CallSysop;
  30. extern char ExitToMsdos;
  31. extern char whichIO;
  32. extern int exitValue;
  33. extern char onConsole; /* Where IO is ... */
  34. extern logBuffer logBuf;         /* Buffer for the pippuls       */
  35. extern aRoom  roomBuf;           /* Room buffer                  */
  36. extern char ForceNet,anyEcho;
  37.  
  38.  
  39. /* EXTERNS */
  40. void Save_Modem(char *,int ,char *);
  41. void Do_Stack_Check(void);
  42. void Dos_Error(long,char *);
  43. void ReActivate_Window(void);  /* allow window to be activated */
  44. int BufferModemFlush(void);
  45. int OpenSerialPorts(void);
  46. int CloseSerial(int final);
  47. void CloseSerialPorts(void);
  48. int Handle_Window_Msg(struct IntuiMessage *InMsg);
  49. int Handle_Little_Window_Msg(struct IntuiMessage *InMsg);
  50. int OpenLittleWindow(void);
  51. int CloseLittleWindow(void);
  52. int BufferConsoleFlush(void);
  53. int OpenConsoleStuff(void);
  54. int CloseConsoleStuff(void);
  55. struct Message *MyGetMsg(struct MsgPort *MyMsgPort);
  56. /*
  57. void  DebugIoRequest (char * string,struct IOExtSer *iorequest);
  58. void DebugIoStdReq(struct IOStdReq *Std);
  59. void Debug_Unit(   struct Unit *Un);
  60. void Debug_Device( struct Device *Dev);
  61. void Debug_Message(struct Message *Msg);
  62. void Debug_Device( struct Device *Dev);
  63. void Debug_space(void);
  64. */
  65. void timer(unsigned long t[2]);
  66. /* GLOBALS */
  67. extern char *VERSION;
  68. struct IntuitionBase *IntuitionBase = NULL;
  69. struct GfxBase       *GfxBase = NULL;
  70. /*struct Library       *ReqBase = NULL; */
  71. struct RastPort      *myScreensRPort = NULL;
  72. UWORD myScreensBLine = 6;
  73. char ConOpen = FALSE;
  74. char UsingREXX = FALSE;
  75. unsigned char conletter,serletter;
  76. short SerialOpen = 0,TimerOpen = 1,probval,oldfrom,serqueued = FALSE,conqueued = FALSE;
  77. struct IOStdReq    *consoleReadMsg   = NULL;
  78. struct MsgPort     *consoleReadPort  = NULL;
  79. struct IOStdReq    *consoleWriteMsg  = NULL;
  80. struct MsgPort     *consoleWritePort = NULL;
  81. struct IOExtSer    *mySerReadMsg     = NULL;
  82. struct MsgPort     *mySerReadPort    = NULL;
  83. struct IOExtSer    *mySerWriteMsg    = NULL;
  84. struct MsgPort     *mySerWritePort   = NULL;
  85. struct IOExtSer    *mySerStatusMsg   = NULL;
  86. struct MsgPort     *mySerStatusPort  = NULL;
  87. struct timerequest *myTimerMsg       = NULL;
  88. struct MsgPort     *myTimerPort      = NULL;
  89.  
  90. extern char logNetResults;
  91. extern FILE *netLog;
  92.  
  93. long char_out;                 /* total characters output */
  94. extern long char_in;           /* total characters input */
  95. extern long start_time;        /* total time for net session */
  96.  
  97. long total_time;               /* total time for all net sessions */
  98. long total_char_in;            /* totals for all time */
  99. long total_char_out;           /* totals for all time */
  100. int level;
  101.  
  102. #ifdef HANDLE_FALSE_CARRIER
  103. struct MsgPort     *SpecialMP;
  104. char SpecialMPName[32];
  105. struct MySpecialMessage
  106.   {
  107.   struct Message Message;
  108.   APTR FCAddress;
  109.  
  110.   }
  111. *SpecialMsg;
  112. #endif
  113. struct Screen *myScreen = NULL;
  114. struct NewScreen myNewScreen =
  115.   {
  116.   0,0,640,200,1,0,1,
  117.   HIRES, CUSTOMSCREEN, NULL, ">>>--> Citadel BBS <--<<<",
  118.   NULL, NULL
  119.  
  120.   };
  121.  
  122. char window_title[84];
  123. char NewScreenTitle[84];
  124. char lastuser[28];
  125. char NewWindowTitle[84];
  126. /*
  127. ** Screen/Window  Title format
  128. ** 1                   23                39
  129. ** [ Citadel Version | Date/Time stamp | System Status      ]
  130. ** 1                   25                              50
  131. ** [ Current User    | Current Room                   | Previous User     ]
  132. */
  133. struct Window *myWindow = NULL, *LittleWindow = NULL;
  134. struct NewWindow myNewWindow =
  135.   {
  136.   0,10,640,190,(UBYTE)-1,(UBYTE)-1,
  137.   CLOSEWINDOW,
  138.   SMART_REFRESH|NOCAREREFRESH|BORDERLESS|RMBTRAP|
  139.   WINDOWCLOSE|WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH,
  140.   NULL, NULL, NULL, NULL, NULL,
  141.   200,40, 1000,1000, CUSTOMSCREEN
  142.  
  143.   };
  144. long timerworks = FALSE;
  145. long timercount = 0;
  146. char internalserial;
  147. #ifdef HANDLE_FALSE_CARRIER
  148. char FalseCarrier = 0;
  149. #endif
  150. UBYTE OpenSerFlags;
  151. struct Task    *MyTask    = NULL;
  152. struct Process *MyProcess = NULL;
  153. struct CommandLineInterface *CLI;
  154. ULONG TStackSz, PStackSz, DefStackSz;
  155. char WBWindow,CLINum;
  156. #define TALKTOREXX
  157. #ifdef TALKTOREXX
  158. /*
  159. *   We need our include file.
  160. */
  161. #include "minrexx.h"
  162. /*
  163. *   These are the REXX functions defined at the bottom of the file.
  164. */
  165. int disp(struct RexxMsg *msg, struct rexxCommandList *dat, char *p);
  166. void rexxsetchat(struct RexxMsg *msg, char *p);
  167. void rexxsetecho(struct RexxMsg *msg, char *p);
  168. void rexxsetnud(struct RexxMsg *msg, char *p);
  169. void rexxexit(struct RexxMsg *msg, char *p);
  170. void rexxversion(struct RexxMsg *msg, char *p);
  171. void rexxserialenable(struct RexxMsg *msg, char *p);
  172. void rexxopenconsole(struct RexxMsg *msg, char *p);
  173. void rexxiconify(struct RexxMsg *msg, char *p);
  174. #ifdef HANDLE_FALSE_CARRIER
  175. void rexxcarrier(struct RexxMsg *msg, char *p);
  176. #endif
  177. /*
  178. *   Here is our command association list.  Note that in this case,
  179. *   we are setting the userdata field to be a function to call.
  180. *   Dispatch will still take place through moodisp(), so common head
  181. *   and tail stuff can go there.
  182. *
  183. *   Commands are all lower case, so we match either upper or lower.
  184. *   (This is a requirement of minrexx.)
  185. */
  186. struct rexxCommandList rcl[] =
  187.   {
  188.     { "setchat",          (APTR)rexxsetchat },
  189.     { "setecho",          (APTR)rexxsetecho },
  190.     { "setnouserdisable", (APTR)rexxsetnud },
  191.     { "exit",             (APTR)rexxexit },
  192.     { "version",          (APTR)rexxversion },
  193.     { "serialenable",     (APTR)rexxserialenable },
  194.     { "openconsole",      (APTR)rexxopenconsole },
  195.     { "iconify",          (APTR)rexxiconify },
  196.   #ifdef HANDLE_FALSE_CARRIER
  197.     { "carrier",          (APTR)rexxcarrier },
  198.   #endif
  199.     { NULL, NULL } };
  200. #endif
  201.  
  202. unsigned long Set_Timer(unsigned long oldtime ) /* return the delta from oldtime in microsecs*/
  203.   {
  204.   unsigned long clock[2];
  205.   timer(clock);      /* get old time */
  206.   return ( clock[0] - oldtime );
  207.   }
  208.  
  209. static char lognet[80];
  210. static char date2[6], date1[6];
  211. static void Write_Total_Data(void);
  212. void Read_Total_Data(void);
  213.  
  214. void Read_Total_Data()
  215.   {
  216.   char *mon;
  217.   FILE *ip;
  218.   int lyr, ldum;
  219.   if( cfg.Audit == 0 )return;
  220.   makeAuditName(lognet, "Network_stats.sys");
  221.   if( (ip = fopen(lognet, "r")) != NULL )
  222.     {
  223.     fread(&date1,         6, 1, ip);
  224.     fread(&total_time,    4, 1, ip);
  225.     fread(&total_char_in, 4, 1, ip);
  226.     fread(&total_char_out,4, 1, ip);
  227.     fclose(ip);
  228.     getCdate(&lyr,&mon,&ldum,&ldum,&ldum);
  229.     sprintf(date2,"%3s%2d",mon,lyr);      /* monthYear */
  230.     if( strcmp(date1,date2) != 0 )
  231.       {
  232.       /* reset, new month  */
  233.       getCdate(&lyr,&mon,&ldum,&ldum,&ldum);
  234.       sprintf(date1,"%3s%2d",mon,lyr);      /* monthYear */
  235.       total_time    = 0;
  236.       total_char_in = 0;
  237.       total_char_out= 0;
  238.       Write_Total_Data();
  239.       }
  240.     }
  241.   else   /* no file, create it */
  242.     {
  243.     getCdate(&lyr,&mon,&ldum,&ldum,&ldum);
  244.     sprintf(date1,"%3s%2d",mon,lyr);      /* monthYear */
  245.     total_time    = 0;
  246.     total_char_in  = 0;   /* new file */
  247.     total_char_out = 0;
  248.     Write_Total_Data();
  249.     }
  250.   }
  251.  
  252. static void Write_Total_Data()
  253.   {
  254.   FILE *ip;
  255.   if( cfg.Audit == 0 )return;
  256.   makeAuditName(lognet, "Network_stats.sys");
  257.   if( (ip = fopen(lognet, "w")) != NULL )
  258.     {
  259.     fwrite(date1,          6, 1, ip);
  260.     fwrite(&total_time,    4, 1, ip);
  261.     fwrite(&total_char_in, 4, 1, ip);
  262.     fwrite(&total_char_out,4, 1, ip);
  263.     fclose(ip);
  264.     }
  265.   }
  266.  
  267. void Compute_Data(char *name)
  268.   {
  269.   int lyr,ldum;
  270.   char *mon;
  271.   FILE *ip;
  272.   long cps;           /* computed data rate */
  273.   long work_time;
  274.   work_time = Set_Timer(start_time);
  275.   if( logNetResults )
  276.     {
  277.     cps = ( char_in + char_out ) / work_time;
  278.     splitF(netLog," Characters Input:%ld Characters Output:%ld  %ld cps\n", char_in, char_out, cps);
  279.     if( cfg.Audit  )
  280.       {
  281.       makeAuditName(lognet,"Network_Istats.sys");
  282.       if( (ip = fopen(lognet, "a")) != NULL)
  283.         {
  284.         getCdate(&lyr,&mon,&ldum,&ldum,&ldum);
  285.         sprintf(date2,"%3s%2d",mon,lyr);      /* monthYear */
  286.         fprintf(ip,"%s %20s %10ld %10ld %10ld\n",date2,name, char_in, char_out, work_time);
  287.         fclose(ip);
  288.         };
  289.  
  290.       };
  291.     }
  292.   Read_Total_Data();
  293.   total_time     += work_time;
  294.   total_char_in  += char_in;
  295.   total_char_out += char_out;
  296.   Write_Total_Data();
  297.   }
  298.  
  299. int nodie(void)
  300.   {
  301.   Do_Stack_Check();
  302.   return(0);
  303.  
  304.   }
  305. int openStuff(void)
  306.   {
  307.   int error;
  308.   extern char anyEcho;
  309.   extern char BpsSet;
  310.   extern long byteRate;
  311.   extern long BaudTable[];
  312.   #ifdef TALKTOREXX
  313.   /*
  314.   *   If we are talking to REXX, we need this additional local.
  315.   */
  316.   long rexxbit ;
  317.   #endif
  318.   Do_Stack_Check();
  319.   probval   = 99;
  320.   termWidth = 40;
  321.   total_char_in = total_char_out = 0;
  322.   IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",33);
  323.   if (!IntuitionBase)
  324.     {
  325.     Dos_Error(1,"Open intuition.Library failed");
  326.     probval = 1;
  327.     goto thisend;
  328.  
  329.     }
  330.   GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0);
  331.   if (!GfxBase)
  332.     {
  333.     Dos_Error(2,"Open graphics.library failed");
  334.     probval = 2;
  335.     goto thisend;
  336.  
  337.     }
  338. /*
  339.   ReqBase = (struct Library *)OpenLibrary("req.library",0);
  340.   if (!ReqBase)
  341.     {
  342.     Dos_Error(2,"Open req.library failed");
  343.     probval = 2;
  344.     goto thisend;
  345.  
  346.     }
  347. */
  348.   MyTask     = FindTask(0L);
  349.   MyProcess  = (struct Process *)MyTask;
  350.   CLI = (struct CommandLineInterface *)(MyProcess->pr_CLI << 2);
  351.   if( CLI )
  352.     {
  353.     DefStackSz = CLI->cli_DefaultStack << 2;
  354.     }
  355.   else
  356.     {
  357.     DefStackSz = MyProcess->pr_StackSize;
  358.     };
  359.   if( DefStackSz < CITADEL_REQUIRED_STACK )
  360.     {
  361.     printf("Current Default Stack = %ld\n",DefStackSz);
  362.     printf("This program needs a stack greater than %ld\n",CITADEL_REQUIRED_STACK);
  363.     Dos_Error(3,"Insufficient Stack Space allocated");
  364.     probval = 3;
  365.     goto thisend;
  366.  
  367.     }
  368.   WBWindow = cfg.DepData.ScreenDepth;
  369.   error    = OpenConsoleStuff();
  370.   if (error < 0)
  371.     {
  372.     Dos_Error(error,"Console Open Error");
  373.     probval = 11;
  374.     goto thisend;
  375.  
  376.     }
  377.   #ifdef CTDL_BACKGROUND
  378.   Close(_Backstdout);
  379.   _Backstdout = 0;
  380.   #endif
  381.   anyEcho = cfg.DepData.StartUpEcho;
  382.   onbreak(nodie);
  383.   error = OpenSerialPorts();
  384.   if (error == ERROR)
  385.     {
  386.     probval = 25;
  387.     Dos_Error(probval,"Open Serial Port Failed");
  388.     goto thisend;
  389.  
  390.     }
  391.   SerialOpen = FALSE;
  392.   myTimerPort = CreatePort(0,0);
  393.   if (!myTimerPort)
  394.     {
  395.     probval = 31;
  396.     Dos_Error(probval,"Create Port Failed");
  397.     goto thisend;
  398.  
  399.     }
  400.   myTimerMsg = (struct timerequest *)CreateExtIO(myTimerPort, sizeof(struct timerequest));
  401.   if (!myTimerMsg)
  402.     {
  403.     probval = 32;
  404.     Dos_Error(probval,"Create I/O Requests Failed");
  405.     goto thisend;
  406.  
  407.     }
  408.   TimerOpen = OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)myTimerMsg,0);
  409.   if (TimerOpen != 0)
  410.     {
  411.     probval = 33;
  412.     Dos_Error(probval,"Open timer.device failed");
  413.     goto thisend;
  414.  
  415.     }
  416.   timerworks = TRUE;
  417.   #ifdef TALKTOREXX
  418.   /*
  419.   *   For rexx, we open up a Rexx port, and send out the first command,
  420.   *   if there was one.  We send it out asynchronously; no reason not to.
  421.   */
  422.   sprintf(ARexx_Name,"Citadel_68K");
  423.   if( FindPort(ARexx_Name) != NULL )
  424.     {
  425.     sprintf(ARexx_Name,"Citadel_68K_%d",CLINum);
  426.     if( FindPort(ARexx_Name) != NULL )
  427.       {
  428.       printf("Unique ARexx_Port Name Failure:%s\n",ARexx_Name);
  429.       };
  430.     };
  431.   rexxbit = upRexxPort(ARexx_Name, rcl, "rexx", &disp) ;
  432.   if (rexxbit != 0)
  433.     {
  434.     UsingREXX = TRUE;
  435.     printf("Rexx Port Name [Citadel_68K]\n ");
  436.  
  437.     }
  438.   #endif
  439.   #ifdef HANDLE_FALSE_CARRIER
  440.   sPrintf(SpecialMPName,"Citadel68K_Spcl_%d",CLINum);
  441.   SpecialMP = CreatePort(SpecialMPName,0);
  442.   if (SpecialMP)
  443.     {
  444.     printf("Special Port Name [%s]\n ",SpecialMPName);
  445.     #ifdef AUTO_EXEC_FALSECARRIER
  446.     sPrintf(NewWindowTitle,"run jays:falsecarrier/fc %d",CLINum);
  447.     Execute(NewWindowTitle,0L,0L);
  448.     WaitPort(SpecialMP);
  449.     SpecialMsg = (struct MySpecialMsg *)GetMsg(SpecialMP);
  450.     if (SpecialMsg)
  451.       {
  452.       SpecialMsg->FCAddress = &FalseCarrier;
  453.       ReplyMsg((struct Message *)SpecialMsg);
  454.  
  455.       }
  456.     #endif
  457.  
  458.     }
  459.   #endif
  460.   if (!BpsSet)  byteRate = (BaudTable[cfg.sysBaud] / 10L);
  461.   thisend:
  462.   if (probval != 99)
  463.     {
  464.     fprintf(stderr, "Startup Error Code %d\n",probval);
  465.     }
  466.   else       printf("System Initialized ok\n");
  467.   strcpy(lastuser," ***None*** ");
  468.   return (probval);
  469.  
  470.   }
  471. void closeStuff(int oldprobval)
  472.   {
  473.   Do_Stack_Check();
  474.   #ifdef TALKTOREXX
  475.   /*
  476.   *   With Rexx, we need to bring the port down.  You might make this
  477.   *   part of exit() for programs that have multiple paths to exit.
  478.   */
  479.   if (UsingREXX) dnRexxPort() ;
  480.   #endif
  481.   #if HANDLE_FALSE_CARRIER
  482.   if (SpecialMP)  DeletePort(SpecialMP);
  483.   #endif
  484.   timerworks = FALSE;
  485.   if ((probval > 34) && !TimerOpen)  CloseDevice((struct IORequest *)myTimerMsg);
  486.   if ((probval > 33) && myTimerMsg)  DeleteExtIO((struct IORequest *)myTimerMsg);
  487.   if ((probval > 32) && myTimerPort) DeletePort(myTimerPort);
  488.   if ((probval > 25) && SerialOpen)  CloseSerial(TRUE);
  489.   if (probval > 25)  CloseSerialPorts();
  490.   if (probval > 11)  CloseConsoleStuff();
  491.   if (LittleWindow)  CloseWindow(LittleWindow);
  492. /*  if (ReqBase)  CloseLibrary(ReqBase); */
  493.   if (GfxBase)  CloseLibrary((struct Library *)GfxBase);
  494.   if (IntuitionBase)  CloseLibrary((struct Library *)IntuitionBase);
  495.  
  496.   }
  497.  
  498.  
  499. #define FULL_BUFFER ( 1279 )
  500. int DoBufferModem,BufferModemCount;
  501. UBYTE ModemBuffer[FULL_BUFFER+1];
  502. int DoBufferConsole,BufferConsoleCount;
  503. char ConsoleBuffer[128];
  504.  
  505. void BufferingOn(void)
  506.   {
  507.   Do_Stack_Check();
  508.   DoBufferModem = TRUE;
  509.   DoBufferConsole = TRUE;
  510.  
  511.   }
  512. void BufferingOff(void)
  513.   {
  514.   Do_Stack_Check();
  515.   DoBufferModem = FALSE;
  516.   BufferModemFlush();
  517.   DoBufferConsole = FALSE;
  518.   BufferConsoleFlush();
  519.  
  520.   }
  521. int BufferModemFlush(void)
  522.   {
  523.   Do_Stack_Check();
  524.   if (SerialOpen && BufferModemCount && gotCarrier())
  525.     {
  526.     mySerWriteMsg->IOSer.io_Data = (APTR)ModemBuffer;
  527.     mySerWriteMsg->IOSer.io_Length = BufferModemCount;
  528.     mySerWriteMsg->IOSer.io_Command = CMD_WRITE;
  529.     char_out += BufferModemCount;
  530.     DoIO((       struct IORequest *)mySerWriteMsg);
  531.     if (cfg.BoolFlags.debug)Save_Modem(ModemBuffer,BufferModemCount,"Out:");
  532.  
  533.     }
  534.   BufferModemCount = 0;
  535.   return(TRUE);
  536.  
  537.   }
  538. char static_send;
  539. char outMod(int character)
  540.   {
  541.   Do_Stack_Check();
  542.   if(DoBufferModem)
  543.     {
  544.     ModemBuffer[BufferModemCount++] = character;
  545.     if(BufferModemCount > FULL_BUFFER )
  546.       {
  547.       BufferModemFlush();
  548.  
  549.       }
  550.  
  551.     }
  552.   else
  553.     {
  554.     if (SerialOpen)
  555.       {
  556.       static_send = character;
  557.       mySerWriteMsg->IOSer.io_Data = (APTR)&static_send;
  558.       mySerWriteMsg->IOSer.io_Length = 1;
  559.       mySerWriteMsg->IOSer.io_Command = CMD_WRITE;
  560.       DoIO(       (struct IORequest *)mySerWriteMsg);
  561.       char_out++;
  562.       if (cfg.BoolFlags.debug)Save_Modem(&static_send,1,"Out:");
  563.  
  564.       }
  565.  
  566.     }
  567.   return(TRUE);
  568.  
  569.   }
  570. int QueueSerRead(int where)
  571.   {
  572.   Do_Stack_Check();
  573.   if (!serqueued && SerialOpen)
  574.     {
  575.     mySerReadMsg->IOSer.io_Command = CMD_READ;
  576.     mySerReadMsg->IOSer.io_Data = (APTR)&serletter;
  577.     mySerReadMsg->IOSer.io_Length = 1;
  578.     char_in++;
  579.     SendIO((struct IORequest *)mySerReadMsg);
  580.     serqueued = TRUE;
  581.  
  582.     }
  583.   return(TRUE);
  584.  
  585.   }
  586. int UnQueueSerRead(void)
  587.   {
  588.   Do_Stack_Check();
  589.   if (serqueued && SerialOpen)
  590.     {
  591.     AbortIO((struct IORequest *)mySerReadMsg);
  592.     WaitPort(mySerReadPort);
  593.     MyGetMsg(mySerReadPort);
  594.     serqueued = FALSE;
  595.  
  596.     }
  597.   return(TRUE);
  598.  
  599.   }
  600. int serPutStr(struct IOExtSer *mess,char *str)
  601.   {
  602.   Do_Stack_Check();
  603.   if (SerialOpen)
  604.     {
  605.     mySerWriteMsg->IOSer.io_Command = CMD_WRITE;
  606.     mySerWriteMsg->IOSer.io_Data = (APTR)str;
  607.     mySerWriteMsg->IOSer.io_Length = strlen(str);
  608.     char_out += mySerWriteMsg->IOSer.io_Length;
  609.     DoIO(       (struct IORequest *)mySerWriteMsg);
  610.     if (cfg.BoolFlags.debug)Save_Modem(str,mySerWriteMsg->IOSer.io_Length," In:");
  611.  
  612.     }
  613.   return(TRUE);
  614.  
  615.   }
  616. #ifdef NEEDED
  617. /*
  618. * This code provided by Gabriel Broner, a s/w engineer at CPT Corp.
  619. *
  620. * First argument is the mask, second argument is a non-ambiguous string to
  621. * check against.
  622. */
  623. testsamefn (s1, s2)
  624. char *s1, *s2;
  625.   {
  626.   Do_Stack_Check();
  627.   if (*s1 == 0)
  628.     {
  629.     if (*(s1 - 1) == '*' || *s2 == 0)
  630.     return TRUE;
  631.     return FALSE;
  632.  
  633.     }
  634.   if (*s2 == 0)
  635.   return FALSE;
  636.   if (*s1 == *s2 || *s1 == '?')
  637.   return testsamefn(s1 + 1, s2 + 1);
  638.   if (*s1 == '*')
  639.   return (testsamefn(s1+1, s2) || testsamefn(s1, s2+1));
  640.   return FALSE;
  641.  
  642.   }
  643. #endif
  644. int OpenSerialPorts(void)
  645.   {
  646.   int erred;
  647.   erred = 0;
  648.   Do_Stack_Check();
  649.   mySerReadPort = CreatePort(0,0);
  650.   if (!mySerReadPort)
  651.     {
  652.     erred = 1;
  653.     Dos_Error(erred,"Create Read Port Failed");
  654.  
  655.     }
  656.   if (!erred)
  657.     {
  658.     mySerReadMsg = (struct IOExtSer *)CreateExtIO(mySerReadPort, sizeof(struct IOExtSer));
  659.     if (!mySerReadMsg)
  660.       {
  661.       erred = 2;
  662.       Dos_Error(erred,"Create Read ExtIO Failed");
  663.  
  664.       }
  665.  
  666.     }
  667.   if (!erred)
  668.     {
  669.     mySerWritePort = CreatePort(0,0);
  670.     if (mySerWritePort == NULL)
  671.       {
  672.       erred = 3;
  673.       Dos_Error(erred,"Create Write Port Failed");
  674.  
  675.       }
  676.  
  677.     }
  678.   if (!erred)
  679.     {
  680.     mySerWriteMsg = (struct IOExtSer *)CreateExtIO(mySerWritePort, sizeof(struct IOExtSer));
  681.     if (mySerWriteMsg == NULL)
  682.       {
  683.       erred = 4;
  684.       Dos_Error(erred,"Create Write ExtIO Failed");
  685.  
  686.       }
  687.  
  688.     }
  689.   if (!erred)
  690.     {
  691.     mySerStatusPort = CreatePort(0,0);
  692.     if (mySerStatusPort == NULL)
  693.       {
  694.       erred = 5;
  695.       Dos_Error(erred,"Create Status Port Failed");
  696.  
  697.       }
  698.  
  699.     }
  700.   if (!erred)
  701.     {
  702.     mySerStatusMsg = (struct IOExtSer *)CreateExtIO(mySerStatusPort,
  703.     sizeof(struct IOExtSer));
  704.     if (mySerStatusMsg == NULL)
  705.       {
  706.       erred = 6;
  707.       Dos_Error(erred,"Create Status ExtIO Failed");
  708.  
  709.       }
  710.  
  711.     }
  712.   if (erred)
  713.     {
  714.     CloseSerialPorts();
  715.  
  716.     }
  717.   return((erred) ? 0 : 1);
  718.  
  719.   }
  720. int OpenSerial(int starting)
  721.   {
  722.   int serror;
  723.   extern long byteRate;
  724.   ULONG devnum;
  725.   char devname[32];
  726.   Do_Stack_Check();
  727.   if (!SerialOpen)
  728.     {
  729.     strncpy(devname,cfg.DepData.DevName,31);
  730.     devname[31] = '\0';
  731.     devnum = cfg.DepData.UnitNumber;
  732.     if (!strcmp(devname,"serial.device") && devnum != 0)
  733.     internalserial = TRUE;
  734.     else  internalserial = FALSE;
  735.     OpenSerFlags = SERF_XDISABLED | SERF_SHARED|SERF_RAD_BOOGIE;
  736.     if (cfg.DepData.Clock & SER_7WIRE)
  737.       {
  738.       OpenSerFlags |= SERF_7WIRE;
  739.       };
  740.     mySerReadMsg->io_SerFlags = OpenSerFlags;
  741.     serror = OpenDevice(devname,devnum,(struct IORequest *)mySerReadMsg,0);
  742.     if (serror != 0)
  743.       {
  744.       Dos_Error(serror,"Open Device for serial port failed");
  745.       return(ERROR);
  746.       };
  747.     mySerWriteMsg->io_SerFlags = OpenSerFlags;
  748.     serror = OpenDevice(devname,devnum,(struct IORequest *)mySerWriteMsg,0);
  749.     if (serror != 0)
  750.       {
  751.       Dos_Error(serror,"Open Device for serial port failed");
  752.       CloseDevice((struct IORequest *)mySerReadMsg);
  753.       return(ERROR);
  754.  
  755.       }
  756.     mySerStatusMsg->io_SerFlags = OpenSerFlags;
  757.     serror = OpenDevice(devname,devnum,(struct IORequest *)mySerStatusMsg,0);
  758.     if (serror != 0)
  759.       {
  760.       Dos_Error(serror,"Open Device for serial port failed");
  761.       CloseDevice((struct IORequest *)mySerReadMsg);
  762.       CloseDevice((struct IORequest *)mySerWriteMsg);
  763.       return(ERROR);
  764.  
  765.       }
  766.     mySerStatusMsg->io_RBufLen  = mySerReadMsg->io_RBufLen  = mySerWriteMsg->io_RBufLen = 2048;
  767.     mySerStatusMsg->io_ReadLen  = mySerReadMsg->io_ReadLen  = mySerWriteMsg->io_ReadLen = 8;
  768.     mySerStatusMsg->io_WriteLen = mySerReadMsg->io_WriteLen = mySerWriteMsg->io_WriteLen = 8;
  769.     mySerStatusMsg->io_StopBits = mySerReadMsg->io_StopBits = mySerWriteMsg->io_StopBits = 1;
  770.     mySerStatusMsg->io_TermArray.TermArray0 = mySerReadMsg->io_TermArray.TermArray0 = mySerWriteMsg->io_TermArray.TermArray0 = NULL;
  771.     mySerStatusMsg->io_TermArray.TermArray1 = mySerReadMsg->io_TermArray.TermArray1 = mySerWriteMsg->io_TermArray.TermArray1 = NULL;
  772.     mySerStatusMsg->IOSer.io_Command = SDCMD_SETPARAMS;
  773.     DoIO(       (struct IORequest *)mySerStatusMsg);
  774.     SerialOpen = TRUE;
  775.     if (byteRate != 0)
  776.       CitadelBaudRate(byteRate, "OpenSerial:byteRate");
  777.     else CitadelBaudRate(cfg.sysBaud,"OpenSerial:sysBaud");
  778.     QueueSerRead(1);
  779.  
  780.     }
  781.   return(TRUE);
  782.  
  783.   }
  784. int CloseSerial(int final)
  785.   {
  786.   Do_Stack_Check();
  787.   if (SerialOpen)
  788.     {
  789.     UnQueueSerRead();
  790.     CloseDevice((struct IORequest *)mySerStatusMsg);
  791.     CloseDevice((struct IORequest *)mySerWriteMsg);
  792.     CloseDevice((struct IORequest *)mySerReadMsg);
  793.     SerialOpen = FALSE;
  794.     return(FALSE);
  795.  
  796.     }
  797.   return(TRUE);
  798.  
  799.   }
  800. void CloseSerialPorts(void)
  801.   {
  802.   Do_Stack_Check();
  803.   if (mySerStatusMsg)
  804.     {
  805.     DeleteExtIO((struct IORequest *)mySerStatusMsg);
  806.     mySerStatusMsg = NULL;
  807.  
  808.     }
  809.   if (mySerWriteMsg)
  810.     {
  811.     DeleteExtIO((struct IORequest *)mySerWriteMsg);
  812.     mySerWriteMsg = NULL;
  813.  
  814.     }
  815.   if (mySerReadMsg)
  816.     {
  817.     DeleteExtIO((struct IORequest *)mySerReadMsg);
  818.     mySerReadMsg = NULL;
  819.  
  820.     }
  821.   if (mySerStatusPort)
  822.     {
  823.     DeletePort(mySerStatusPort);
  824.     mySerStatusPort = NULL;
  825.  
  826.     }
  827.   if (mySerWritePort)
  828.     {
  829.     DeletePort(mySerWritePort);
  830.     mySerWritePort = NULL;
  831.  
  832.     }
  833.   if (mySerReadPort)
  834.     {
  835.     DeletePort(mySerReadPort);
  836.     mySerReadPort = NULL;
  837.  
  838.     }
  839.  
  840.   }
  841. char time_in[30];
  842. char sstatus[30];
  843. int timeupdatecount,old_user;
  844. int old_shr, old_smn;
  845. void ScrTimeUpdate(int shr, int smn)
  846.   {
  847.   Do_Stack_Check();
  848.   timeupdatecount = 0;
  849.   if (!ConOpen) return;
  850.   if( old_shr == shr && old_smn == smn )return;
  851.   old_shr = shr;
  852.   old_smn = smn;
  853.   if (myScreensRPort)
  854.     {
  855.     sPrintf(NewScreenTitle,"Citadel 68K V%s %s| %2d:%02d %7s | %-30s"
  856.     ,VERSION,SysVers,shr,smn,formDate(),sstatus);
  857.     SetWindowTitles(myWindow,window_title,NewScreenTitle);
  858.     }
  859.  
  860.   }
  861. void ScrNewUser(void)
  862.   {
  863.   char temp_title[84],*smo;
  864.   int syr,sdy,shr,smn;
  865.   Do_Stack_Check();
  866.   getCdate(&syr,&smo,&sdy,&shr,&smn);
  867.   if (!ConOpen || !myWindow) return;
  868.   if (!old_user && logBuf.lbname[0])
  869.     {
  870.     sPrintf(time_in,"In: %2d:%02d                    ",shr,smn);
  871.     old_user = 1;
  872.  
  873.     }
  874.   if (!logBuf.lbname[0] && old_user)
  875.     {
  876.     strcpy(time_in," *** None ***               ");
  877.     old_user = 0;
  878.  
  879.     }
  880.   sPrintf(temp_title,"User:%-19s|Room:%-19s|%c%c%c%s|Last:%s"
  881.   ,logBuf.lbname,  roomBuf.rbname,
  882.   (cfg.BoolFlags.noChat) ?  ' ' : 'C',
  883.   (cfg.BoolFlags.debug)  ?  'D' : ' ',
  884.   (anyEcho)              ?  'E' : ' ',
  885.   (CallSysop)            ? "^T" :((ForceNet) ? "^A" : "  "),
  886.   lastuser);
  887.   strncpy(window_title,temp_title,83);
  888.   old_smn = -1;
  889.   SpecialMessage(time_in);
  890.   }
  891. char oldmsg[30];
  892. void SpecialMessage(char *message)
  893.   {
  894.   short j;
  895.   char realmsg[30];
  896.   char *smo;
  897.   int syr,sdy,shr,smn;
  898.   Do_Stack_Check();
  899.   timeupdatecount = 0;
  900.   if (!ConOpen) return;
  901.   if (myScreensRPort)
  902.     {
  903.     j = strlen(message);
  904.     memset(realmsg,'\0',30);
  905.     if( j > 29)j = 29;
  906.     strncpy(realmsg,message,j);
  907.     realmsg[j] = '\0';
  908.     if( strcmp(oldmsg,realmsg) != 0 )      /* do not update unless change*/
  909.       {
  910.       sprintf(sstatus,"%-30s",realmsg);
  911.       getCdate(&syr,&smo,&sdy,&shr,&smn);
  912.       ScrTimeUpdate(shr, smn);
  913.       strcpy(oldmsg,realmsg);
  914.       };
  915.     }
  916.  
  917.   }
  918. /************************************************************************/
  919. /*   pause() busy-waits N/100 seconds            */
  920. /************************************************************************/
  921. void pause(int i)
  922.   {
  923.   ULONG secs, micros;
  924.   Do_Stack_Check();
  925.   if( myTimerMsg == NULL)return;
  926.   secs = i / 100;
  927.   micros = (i - (secs * 100)) * 10000;
  928.   if (!secs && !micros)  micros = 10000;
  929.   if (micros < 0 || micros > 999999)
  930.     {
  931.     printf("[pause(%d) micros = %ld]",i,micros);
  932.     micros = 10000;
  933.  
  934.     }
  935.   myTimerMsg->tr_node.io_Command = TR_ADDREQUEST;
  936.   myTimerMsg->tr_node.io_Message.mn_ReplyPort = myTimerPort;
  937.   myTimerMsg->tr_time.tv_secs = secs;
  938.   myTimerMsg->tr_time.tv_micro = micros;
  939.   DoIO((struct IORequest *)myTimerMsg);
  940.  
  941.   }
  942. void MilliSecPause(int x)
  943.   {  /* really a 100 microsecond delay per x */
  944.   long micros;
  945.   Do_Stack_Check();
  946.   if( myTimerMsg == NULL)return;
  947.   if( x < 1 || x > 1000)x = 1000;  /* out of range, give max */
  948.   micros = x * 100;                /* time in 100 microsecond units */
  949.   myTimerMsg->tr_node.io_Command = TR_ADDREQUEST;
  950.   myTimerMsg->tr_node.io_Message.mn_ReplyPort = myTimerPort;
  951.   myTimerMsg->tr_time.tv_secs  = 0;
  952.   myTimerMsg->tr_time.tv_micro = micros;
  953.   DoIO((struct IORequest *)myTimerMsg);
  954.  
  955.   }
  956. void timer(unsigned long t[2])
  957.   {
  958.   Do_Stack_Check();
  959.   if( myTimerMsg == NULL)return;
  960.   myTimerMsg->tr_node.io_Message.mn_ReplyPort = myTimerPort;
  961.   myTimerMsg->tr_node.io_Command = TR_GETSYSTIME;
  962.   DoIO((struct IORequest *)myTimerMsg);
  963.   t[0] = myTimerMsg->tr_time.tv_secs;
  964.   t[1] = myTimerMsg->tr_time.tv_micro;
  965.  
  966.   }
  967. #ifdef TALKTOREXX
  968. /*
  969. *   Now we get into the actual code necessary for our REXX port; functions
  970. *   that do the real work.  Note that this program was not structured
  971. *   particularly nicely for Rexx; I had to write each of these functions.
  972. *   Many programs have these subroutines already in place; they are called
  973. *   as part of the event loop.  This progam, however, just has one big
  974. *   switch statement with different actions . . .
  975. *
  976. *   First, our locals.
  977. */
  978. int args[4] ;              /* what args did we see to this function? */
  979. int parsed ;               /* was argument parsing successful? */
  980. int userreplied ;          /* has the current message been replied to yet? */
  981. /*
  982. *   This function takes a pointer to a pointer to a string, grabs the
  983. *   next number, returns it, and advances the pointer to the string to
  984. *   point after the number.
  985. */
  986. int getnm(char **where)
  987.   {
  988.   register char *p = *where ;
  989.   register int val = 0 ;
  990.   int gotone = 0 ;
  991.   Do_Stack_Check();
  992.   while (*p <= ' ' && *p)  p++ ;
  993.   while ('0' <= *p && *p <= '9')
  994.     {
  995.     gotone = 1 ;
  996.     val = 10 * val + *p++ - '0' ;
  997.  
  998.     }
  999.   if (gotone == 0)  parsed = 0 ;
  1000.   *where = p ;
  1001.   return(val) ;
  1002.  
  1003.   }
  1004. /*
  1005. *   This function trys to find `n' numeric arguments in the command
  1006. *   string, and stuffs them into the args array.
  1007. */
  1008. void parseargs(char *p, int n)
  1009.   {
  1010.   register int i ;
  1011.   Do_Stack_Check();
  1012.   while (*p > ' ' && *p)  p++ ;
  1013.   for (i=0; i<n; i++)  args[i] = getnm(&p) ;
  1014.  
  1015.   }
  1016. /*
  1017. *   This is our main dispatch function.  We check to make sure a Window
  1018. *   currently exists.  Then, we store away the `current color' and change
  1019. *   it to Rexx's current color, call our handler function, and then restore
  1020. *   the color.  If our handler replied, we return a 1 to indicate that.
  1021. *   If the parse and everything else was successful, we return a 0.
  1022. *   Otherwise, we return a failure of 20 to indicate that the arguments
  1023. *   were messed up.
  1024. */
  1025. int disp(struct RexxMsg *msg, struct rexxCommandList *dat, char *p)
  1026.   {
  1027.   parsed = 1 ;
  1028.   Do_Stack_Check();
  1029.   userreplied = 0 ;
  1030.   ((int (*)())(dat->userdata))(msg, p) ;
  1031.   if (! parsed) replyRexxCmd(msg, (long)parsed, 0L, NULL) ;
  1032.   return TRUE;
  1033.  
  1034.   }
  1035. #endif
  1036. #ifdef TALKTOREXX
  1037. char dorexxexit = FALSE;
  1038. #endif
  1039. int Amiga_System_Input(void)
  1040.   {
  1041.   struct IntuiMessage *InMsg;
  1042.   Do_Stack_Check();
  1043.   #ifdef TALKTOREXX
  1044.   /*
  1045.   *   Handle any Rexx messages.
  1046.   */
  1047.   if (UsingREXX)  dispRexxPort() ;
  1048.   #endif
  1049.   #ifdef HANDLE_FALSE_CARRIER
  1050.   if (SpecialMP)
  1051.     {
  1052.     SpecialMsg = (struct MySpecialMsg *)GetMsg(SpecialMP);
  1053.     if (SpecialMsg)
  1054.       {
  1055.       SpecialMsg->FCAddress = &FalseCarrier;
  1056.       ReplyMsg(SpecialMsg);
  1057.  
  1058.       }
  1059.  
  1060.     }
  1061.   #endif
  1062.   if (ConOpen)
  1063.     {
  1064.     InMsg = (struct IntuiMessage *)GetMsg(myWindow->UserPort);
  1065.     if (InMsg != NULL) Handle_Window_Msg(InMsg);
  1066.  
  1067.     }
  1068.   if (LittleWindow != NULL)
  1069.     {
  1070.     InMsg = (struct IntuiMessage *)GetMsg(LittleWindow->UserPort);
  1071.     if (InMsg != NULL) Handle_Little_Window_Msg(InMsg);
  1072.  
  1073.     }
  1074.   return(0);
  1075.  
  1076.   }
  1077. #ifdef TALKTOREXX
  1078. void rexxsetchat(struct RexxMsg *msg, char *p)
  1079.   {
  1080.   Do_Stack_Check();
  1081.   parseargs(p, 1) ;
  1082.   cfg.BoolFlags.noChat = (args[0]) ? FALSE : TRUE;
  1083.   ScrNewUser();
  1084.  
  1085.   }
  1086. void rexxsetecho(struct RexxMsg *msg, char *p)
  1087.   {
  1088.   Do_Stack_Check();
  1089.   parseargs(p, 1) ;
  1090.   anyEcho = (args[0]) ? TRUE : FALSE;
  1091.   ScrNewUser();
  1092.  
  1093.   }
  1094. void rexxsetnud(struct RexxMsg *msg, char *p)
  1095.   {
  1096.   Do_Stack_Check();
  1097.   parseargs(p, 1) ;
  1098.   CallSysop = (args[0]) ? TRUE : FALSE;
  1099.   ScrNewUser();
  1100.  
  1101.   }
  1102. extern char haveCarrier;
  1103. char retstr[4];
  1104. void rexxexit(struct RexxMsg *msg, char *p)
  1105.   {
  1106.   Do_Stack_Check();
  1107.   parseargs(p, 1) ;
  1108.   strcpy(retstr,"0");
  1109.   if (!haveCarrier || args[0] != 0)
  1110.     {
  1111.     ExitToMsdos = TRUE;
  1112.     exitValue = 0;
  1113.     strcpy(retstr,"1");
  1114.  
  1115.     }
  1116.   userreplied = 1;
  1117.   replyRexxCmd(msg, 0L, 0L, retstr) ;
  1118.  
  1119.   }
  1120. void rexxversion(struct RexxMsg *msg, char *p)
  1121.   {
  1122.   Do_Stack_Check();
  1123.   userreplied = 1 ;
  1124.   replyRexxCmd(msg, 0L, 0L, VERSION) ;
  1125.  
  1126.   }
  1127. void rexxserialenable(struct RexxMsg *msg, char *p)
  1128.   {
  1129.   Do_Stack_Check();
  1130.   parseargs(p, 2) ;
  1131.   strcpy(retstr,"0");
  1132.   if (!haveCarrier || args[1] != 0)
  1133.     {
  1134.     if (args[0])
  1135.       {
  1136.       SerialOpen = OpenSerial(FALSE);
  1137.       if (SerialOpen == TRUE) strcpy(retstr,"1");
  1138.  
  1139.       }
  1140.     else
  1141.       {
  1142.       SerialOpen = CloseSerial(FALSE);
  1143.       if (!SerialOpen) strcpy(retstr,"1");
  1144.  
  1145.       }
  1146.  
  1147.     }
  1148.   userreplied = 1;
  1149.   replyRexxCmd(msg, 0L, 0L, retstr) ;
  1150.  
  1151.   }
  1152. void rexxopenconsole(struct RexxMsg *msg, char *p)
  1153.   {
  1154.   Do_Stack_Check();
  1155.   parseargs(p, 1) ;
  1156.   strcpy(retstr,"0");
  1157.   if (args[0])
  1158.     {
  1159.     if (!ConOpen)
  1160.       {
  1161.       OpenConsoleStuff();
  1162.       iconify_window = FALSE;
  1163.       };
  1164.     }
  1165.   else
  1166.     {
  1167.     if (ConOpen)
  1168.       {
  1169.       if (whichIO == MODEM)
  1170.         {
  1171.         CloseConsoleStuff();
  1172.         iconify_window = TRUE;
  1173.         };
  1174.       };
  1175.     };
  1176.   if (ConOpen)
  1177.   strcpy(retstr,"1");
  1178.   else
  1179.   strcpy(retstr,"0");
  1180.   userreplied = 1;
  1181.   replyRexxCmd(msg, 0L, 0L, retstr) ;
  1182.  
  1183.   }
  1184. void rexxiconify(struct RexxMsg *msg, char *p)
  1185.   {
  1186.   int error;
  1187.   Do_Stack_Check();
  1188.   parseargs(p, 1) ;
  1189.   strcpy(retstr,"0");
  1190.   if (args[0])
  1191.     {
  1192.     if (ConOpen)
  1193.       {
  1194.       if (whichIO == MODEM)
  1195.         {
  1196.         error = OpenLittleWindow();
  1197.         if (error == TRUE)
  1198.           {
  1199.           CloseConsoleStuff();
  1200.           strcpy(retstr,"1");
  1201.           iconify_window = TRUE;
  1202.           }
  1203.  
  1204.         }
  1205.  
  1206.       }
  1207.  
  1208.     }
  1209.   else
  1210.     {
  1211.     if (!ConOpen)
  1212.       {
  1213.       error = OpenConsoleStuff();
  1214.       if (error > 0)
  1215.         {
  1216.         strcpy(retstr,"1");
  1217.         if (LittleWindow != NULL)
  1218.         CloseLittleWindow();
  1219.         iconify_window = FALSE;
  1220.  
  1221.         }
  1222.  
  1223.       }
  1224.  
  1225.     }
  1226.  
  1227.   userreplied = 1;
  1228.   replyRexxCmd(msg, 0L, 0L, retstr) ;
  1229.  
  1230.   }
  1231. #ifdef HANDLE_FALSE_CARRIER
  1232. void rexxcarrier(struct RexxMsg *msg, char *p)
  1233.   {
  1234.   Do_Stack_Check();
  1235.   parseargs(p, 1) ;
  1236.   FalseCarrier = (args[0]) ? TRUE : FALSE;
  1237.  
  1238.   }
  1239. #endif
  1240. #endif
  1241. int Handle_Window_Msg(struct IntuiMessage *InMsg)
  1242.   {
  1243.   ULONG msgclass;
  1244.   int err;
  1245.   Do_Stack_Check();
  1246.   msgclass = InMsg->Class;
  1247.   ReplyMsg((struct Message *)InMsg);
  1248.   if (msgclass == CLOSEWINDOW)
  1249.     {
  1250.     if (whichIO == MODEM)
  1251.       {
  1252.       err = OpenLittleWindow();
  1253.       if (err == FALSE)
  1254.         {
  1255.         DisplayBeep(NULL);
  1256.  
  1257.         }
  1258.       else
  1259.         {
  1260.         CloseConsoleStuff();
  1261.  
  1262.         }
  1263.  
  1264.       }
  1265.  
  1266.     }
  1267.   return(TRUE);
  1268.  
  1269.   }
  1270. int Handle_Little_Window_Msg(struct IntuiMessage *InMsg)
  1271.   {
  1272.   int err;
  1273.   Do_Stack_Check();
  1274.   ReplyMsg((struct Message *)InMsg);
  1275.   err = OpenConsoleStuff();
  1276.   if (err < 1)
  1277.     {
  1278.     DisplayBeep(NULL);
  1279.  
  1280.     }
  1281.   else
  1282.     {
  1283.     CloseLittleWindow();
  1284.  
  1285.     }
  1286.   return(TRUE);
  1287.  
  1288.   }
  1289. struct NewWindow NewLittleWindow =
  1290.   {
  1291.   100,0,188,12,(UBYTE)-1,(UBYTE)-1,
  1292.   CLOSEWINDOW,
  1293.   WINDOWDEPTH | WINDOWCLOSE | WINDOWDRAG | SMART_REFRESH | RMBTRAP,
  1294.   NULL, NULL,
  1295.   (UBYTE *)"Amiga Citadel",
  1296.   NULL,NULL,0,0,1000,1000,WBENCHSCREEN
  1297.  
  1298.   };
  1299. int OpenLittleWindow(void)
  1300.   {
  1301.   Do_Stack_Check();
  1302.   if (LittleWindow == NULL)
  1303.     {
  1304.     LittleWindow = OpenWindow(&NewLittleWindow);
  1305.  
  1306.     }
  1307.   if (LittleWindow != NULL)
  1308.   return(1);
  1309.   return(0);
  1310.  
  1311.   }
  1312. int CloseLittleWindow(void)
  1313.   {
  1314.   Do_Stack_Check();
  1315.   if (LittleWindow != NULL)
  1316.     {
  1317.     CloseWindow(LittleWindow);
  1318.     LittleWindow = NULL;
  1319.     return(1);
  1320.  
  1321.     }
  1322.   else return(0);
  1323.  
  1324.   }
  1325.  
  1326. int Jsystem(char *cmdline)
  1327.   {
  1328.   long ecode;
  1329.   char dir[80];
  1330.   BPTR nilfh;
  1331.   Do_Stack_Check();
  1332.   if (cfg.BoolFlags.debug)
  1333.     {
  1334.     (void)getcd(0,dir);
  1335.     splitF(netLog, " Dir:%s\n Command:%s\n",dir,cmdline);
  1336.     };
  1337.   (void)SetIoErr(0);       /* initialize the error code */
  1338.   pause(1);
  1339.   nilfh = Open("NIL:",MODE_OLDFILE);
  1340.   Execute(cmdline,NULL,nilfh);  /* execute the command */
  1341.   ecode = IoErr();          /* check for error */
  1342.   if( ecode != 0 )Dos_Error(ecode,cmdline);
  1343.   return((int)ecode);
  1344.   }
  1345.  
  1346. void Dos_Error(err,str)   /* format a AmigaDos Error and put in debug.sys */
  1347. long err;
  1348. char *str;
  1349.   {
  1350.   char *mon;
  1351.   int yr,day,hour,min;
  1352.   char buf[80];
  1353.   char CLogFn[80];            /* buffer for calllog.sys */
  1354.   Do_Stack_Check();
  1355.   if( cfg.Audit == 0)return;  /* exit if the Sysop has not configed Auditing*/
  1356.   makeAuditName(CLogFn, "debug.sys");
  1357.   getCdate(&yr,&mon,&day,&hour,&min);
  1358.   sprintf(buf,"%2d%s%02d %d:%02d - Dos Error:%ld",yr,mon,day,hour,min,err);
  1359.   CallMsg(CLogFn,buf);        /* time and date of the error */
  1360.   sprintf(buf,"%s",str);
  1361.   CallMsg(CLogFn, buf);       /* report the command */
  1362.   (void)Fault(err,"Reason:",buf,80);
  1363.   CallMsg(CLogFn, buf);       /* report the error in text */
  1364.   (void)getcd(0,buf);
  1365.   CallMsg(CLogFn, buf);       /* report the current directory */
  1366.   pause(3);
  1367.   }
  1368.  
  1369. void ReActivate_Window()
  1370.   {
  1371.   Do_Stack_Check();
  1372.   if( !ConOpen ) OpenConsoleStuff();/* reactivate window if closed */
  1373.   ScreenToFront(myWindow->WScreen); /* make sure that the screen is front */
  1374.   WindowToFront(myWindow);          /* make sure the window is in front */
  1375.   ActivateWindow(myWindow);         /* activate, it can't hurt */
  1376.   }
  1377.  
  1378. int QueueRead(struct IOStdReq *request,char *whereto)
  1379.   {
  1380.   Do_Stack_Check();
  1381.   if (ConOpen && !conqueued)
  1382.     {
  1383.     consoleReadMsg->io_Command = CMD_READ;
  1384.     consoleReadMsg->io_Data = (APTR)&conletter;
  1385.     consoleReadMsg->io_Length = 1;
  1386.     SendIO((struct IORequest *)consoleReadMsg);
  1387.     conqueued = TRUE;
  1388.  
  1389.     }
  1390.   return(TRUE);
  1391.  
  1392.   }
  1393. int UnQueueRead(void)
  1394.   {
  1395.   Do_Stack_Check();
  1396.   if (conqueued && ConOpen)
  1397.     {
  1398.     AbortIO((struct IORequest *)consoleReadMsg);
  1399.     WaitPort(consoleReadPort);
  1400.     MyGetMsg(consoleReadPort);
  1401.     conqueued = FALSE;
  1402.  
  1403.     }
  1404.   return(TRUE);
  1405.  
  1406.   }
  1407. int ConPutStr(char *myString)
  1408.   {
  1409.   Do_Stack_Check();
  1410.   if (!ConOpen || !myString || !strlen(myString))  return(0);
  1411.   consoleWriteMsg->io_Command = CMD_WRITE;
  1412.   consoleWriteMsg->io_Data = (APTR)myString;
  1413.   consoleWriteMsg->io_Length = strlen(myString);
  1414.   DoIO((struct IORequest *)consoleWriteMsg);
  1415.   return(1);
  1416.  
  1417.   }
  1418. int BufferConsoleFlush(void)
  1419.   {
  1420.   Do_Stack_Check();
  1421.   if (ConOpen && BufferConsoleCount)
  1422.     {
  1423.     consoleWriteMsg->io_Data = (APTR)ConsoleBuffer;
  1424.     consoleWriteMsg->io_Length = BufferConsoleCount;
  1425.     consoleWriteMsg->io_Command = CMD_WRITE;
  1426.     DoIO((struct IORequest *)consoleWriteMsg);
  1427.  
  1428.     }
  1429.   BufferConsoleCount = 0;
  1430.   return(TRUE);
  1431.  
  1432.   }
  1433. int ConPutChar(char myChar)
  1434.   {
  1435.   Do_Stack_Check();
  1436.   if (DoBufferConsole)
  1437.     {
  1438.     ConsoleBuffer[BufferConsoleCount++] = myChar;
  1439.     if(BufferConsoleCount > 126)
  1440.       {
  1441.       BufferConsoleFlush();
  1442.  
  1443.       }
  1444.  
  1445.     }
  1446.   else
  1447.     {
  1448.     if (ConOpen)
  1449.       {
  1450.       consoleWriteMsg->io_Command = CMD_WRITE;
  1451.       consoleWriteMsg->io_Data = (APTR)&myChar;
  1452.       consoleWriteMsg->io_Length = 1;
  1453.       DoIO((struct IORequest *)consoleWriteMsg);
  1454.  
  1455.       }
  1456.  
  1457.     }
  1458.   return(TRUE);
  1459.  
  1460.   }
  1461. int OpenConsoleStuff(void)
  1462.   {
  1463.   UWORD tmpcolors[2];
  1464.   int error,erred;
  1465.   Do_Stack_Check();
  1466.   if (ConOpen)  return(1);
  1467.   erred = 0;
  1468.   if (!WBWindow)
  1469.     {
  1470.     myNewScreen.Width     = cfg.DepData.ScreenWidth;
  1471.     myNewScreen.Height    = cfg.DepData.ScreenHeight;
  1472.     myNewScreen.Depth     = 1;  /* 3;   /* 8 colors */
  1473.     if (cfg.DepData.ScreenHeight > 399) myNewScreen.ViewModes |= LACE;
  1474.     sPrintf(NewScreenTitle,"Amiga Citadel V%s %s",VERSION,SysVers);
  1475.     myNewScreen.DefaultTitle = (UBYTE *)NewScreenTitle;
  1476.     myScreen = (struct Screen *)OpenScreen(&myNewScreen);
  1477.     if (!myScreen) return(-1);
  1478.     myNewWindow.Screen = myScreen;
  1479.     myScreensRPort = &(myScreen->RastPort);
  1480.     myScreensBLine = myScreensRPort->Font->tf_Baseline + 1;
  1481.  
  1482.     }
  1483.   else
  1484.     {
  1485.     myNewWindow.Type    = WBENCHSCREEN;
  1486.     myNewWindow.Screen  = NULL;
  1487.     myScreensRPort      = NULL;
  1488.     myNewWindow.TopEdge = 0;
  1489.  
  1490.     }
  1491.   strcpy(NewWindowTitle,"Citadel Console");
  1492.   myNewWindow.Title = (UBYTE *)NewWindowTitle;
  1493.   myNewWindow.Width = cfg.DepData.ScreenWidth;
  1494.   if (!WBWindow)
  1495.     {
  1496.     myNewWindow.Height     = cfg.DepData.ScreenHeight - 10;
  1497.     myNewWindow.Flags     &= ~(WINDOWSIZING | WINDOWDRAG);
  1498.  
  1499.     }
  1500.   else  myNewWindow.Height = cfg.DepData.ScreenHeight;
  1501.   myWindow                 = OpenWindow(&myNewWindow);
  1502.   if (!myWindow)
  1503.     {
  1504.     if(myScreen)
  1505.       {
  1506.       CloseScreen(myScreen);
  1507.       myScreen = NULL;
  1508.  
  1509.       }
  1510.     return(-2);
  1511.  
  1512.     };
  1513.   if (myScreen)
  1514.     {
  1515.     tmpcolors[0] = cfg.DepData.Color0;
  1516.     tmpcolors[1] = cfg.DepData.Color1;
  1517.     LoadRGB4(ViewPortAddress(myWindow),tmpcolors,2);
  1518.     ((struct Process *)FindTask(0))->pr_WindowPtr = (APTR)myWindow;
  1519.  
  1520.     };
  1521.   consoleReadPort = CreatePort(0,0);
  1522.   if (!consoleReadPort)
  1523.     {
  1524.     erred = 3;
  1525.  
  1526.     }
  1527.   if (!erred)
  1528.     {
  1529.     consoleReadMsg = (struct IOStdReq *)CreateExtIO(consoleReadPort, sizeof(struct IOStdReq));
  1530.     if (!consoleReadMsg)
  1531.       {
  1532.       erred = 4;
  1533.  
  1534.       }
  1535.  
  1536.     }
  1537.   if (!erred)
  1538.     {
  1539.     consoleWritePort = CreatePort(0,0);
  1540.     if (!consoleWritePort)
  1541.       {
  1542.       erred = 5;
  1543.  
  1544.       }
  1545.  
  1546.     }
  1547.   if (!erred)
  1548.     {
  1549.     consoleWriteMsg = (struct IOStdReq *)CreateExtIO(consoleWritePort, sizeof(struct IOStdReq));
  1550.     if (!consoleWriteMsg)
  1551.       {
  1552.       erred = 6;
  1553.  
  1554.       }
  1555.  
  1556.     }
  1557.   if (!erred)
  1558.     {
  1559.     consoleReadMsg->io_Data = (APTR)myWindow;
  1560.     consoleReadMsg->io_Length = sizeof(struct Window);
  1561.     error = OpenDevice("console.device",0,(struct IORequest *)consoleReadMsg,0);
  1562.     if (error)
  1563.       {
  1564.       erred = 7;
  1565.  
  1566.       }
  1567.  
  1568.     }
  1569.   if (!erred)
  1570.     {
  1571.     consoleWriteMsg->io_Data = (APTR)myWindow;
  1572.     consoleWriteMsg->io_Length = sizeof(struct Window);
  1573.     consoleWriteMsg->io_Device = consoleReadMsg->io_Device;
  1574.     consoleWriteMsg->io_Unit = consoleReadMsg->io_Unit;
  1575.     ConOpen = TRUE;
  1576.     printf("Console opened: Columns = %d, Rows = %d\n ",
  1577.     myNewWindow.Width / myWindow->RPort->TxWidth, (myNewWindow.Height - myWindow->RPort->TxHeight - 2) / myWindow->RPort->TxHeight);
  1578.     QueueRead(consoleReadMsg,&conletter);
  1579.  
  1580.     }
  1581.   ReActivate_Window();
  1582.   if (erred)
  1583.     {
  1584.     CloseConsoleStuff();
  1585.  
  1586.     }
  1587.   return(0-erred);
  1588.  
  1589.   }
  1590. int CloseConsoleStuff(void)
  1591.   {
  1592.   Do_Stack_Check();
  1593.   UnQueueRead();
  1594.   if (ConOpen)  CloseDevice((struct IORequest *)consoleReadMsg);
  1595.   ConOpen = FALSE;
  1596.   if (consoleWriteMsg)
  1597.     {
  1598.     DeleteExtIO((struct IORequest *)consoleWriteMsg);
  1599.     consoleWriteMsg = NULL;
  1600.  
  1601.     }
  1602.   if (consoleWritePort)
  1603.     {
  1604.     DeletePort(consoleWritePort);
  1605.     consoleWritePort = NULL;
  1606.  
  1607.     }
  1608.   if (consoleReadMsg)
  1609.     {
  1610.     DeleteExtIO((struct IORequest *)consoleReadMsg);
  1611.     consoleReadMsg = NULL;
  1612.  
  1613.     }
  1614.   if (consoleReadPort)
  1615.     {
  1616.     DeletePort(consoleReadPort);
  1617.     consoleReadPort = NULL;
  1618.  
  1619.     }
  1620.   if (myWindow)
  1621.     {
  1622.     if (((struct Process *)FindTask(0))->pr_WindowPtr == myWindow)
  1623.     ((struct Process *)FindTask(0))->pr_WindowPtr = (APTR)NULL;
  1624.     CloseWindow(myWindow);
  1625.     myWindow = NULL;
  1626.  
  1627.     }
  1628.   if (myScreen)
  1629.     {
  1630.     CloseScreen(myScreen);
  1631.     myScreen = NULL;
  1632.  
  1633.     }
  1634.   return(TRUE);
  1635.  
  1636.   }
  1637. struct Message *MyGetMsg(struct MsgPort *MyMsgPort)
  1638.   {
  1639.   struct Message *RepliedMessage;
  1640.   Do_Stack_Check();
  1641.   if (RepliedMessage = GetMsg(MyMsgPort))
  1642.     {
  1643.     SetSignal(0L,(1L << MyMsgPort->mp_SigBit));
  1644.  
  1645.     }
  1646.   return(RepliedMessage);
  1647.  
  1648.   }
  1649. int SysdepCheckArg(char *arg)
  1650.   {
  1651.   Do_Stack_Check();
  1652.   return(0);
  1653.  
  1654.   }
  1655. /*
  1656.  * CitSystem()
  1657.  *
  1658.  * This function formats the format & arguments and then runs the result via
  1659.  * system().
  1660.  */
  1661. int CitSystem(char RestoreVideo, char *format, ...)
  1662. {
  1663.     va_list argptr;
  1664.     char *garp;
  1665.     extern char *bigbuffer;
  1666.     Do_Stack_Check();
  1667.     garp = bigbuffer;
  1668.     va_start(argptr, format);
  1669.     vsprintf(garp, format, argptr);
  1670.     va_end(argptr);
  1671. /*    if (RestoreVideo) StopVideo();  */
  1672.     Jsystem(garp);
  1673. /*    if (RestoreVideo) VideoInit();  */
  1674.     return 0;
  1675. }
  1676. unsigned long S_min = 0xFFFFFFFF;  /* min value seen */
  1677. unsigned long S_max = 0x00000000;  /* max value seen */
  1678. void Do_Stack_Check()
  1679.   {
  1680.   unsigned long S_current;
  1681.   S_current = getreg(REG_A7);  /* grab current stack pointer */
  1682.   if( S_current < S_min )S_min = S_current;
  1683.   if( S_current > S_max )S_max = S_current;
  1684.   }
  1685. /*
  1686. ** functions for caller count and user privledges
  1687. */
  1688. char logcall[100];
  1689. long Get_Call_Count()
  1690.   {
  1691.   FILE *ip;
  1692.   long count=0;
  1693.   if( cfg.Audit == 0)return 0;  /* exit if the Sysop has not configed Auditing*/
  1694.   makeAuditName(logcall, "user_count.sys");
  1695.   if( (ip = fopen(logcall,"r")) != NULL)
  1696.     {
  1697.     fread(&count,4,1,ip);
  1698.     fclose(ip);
  1699.     };
  1700.   return count;
  1701.   }
  1702.  
  1703. void Update_Caller_Count()
  1704.   {
  1705.   FILE *ip;
  1706.   long count=0;
  1707.   if( cfg.Audit == 0 ) return; /* Audit Area not setup */
  1708.   makeAuditName(logcall, "user_count.sys");
  1709.   if( (ip = fopen(logcall,"rb")) != NULL)
  1710.     {
  1711.     fread(&count,4,1,ip);
  1712.     fclose(ip);
  1713.     };
  1714.   if( (ip = fopen(logcall,"wb")) != NULL)
  1715.     {
  1716.     fseek(ip,0,SEEK_SET);
  1717.     count++;
  1718.     fwrite(&count,4,1,ip);
  1719.     fclose(ip);
  1720.     };
  1721.   }
  1722.  
  1723. char *Display_Privledges()
  1724.   {
  1725.   extern char      loggedIn;  /* Are we logged in?       */
  1726.   int count=0;                /* check for no privileges */
  1727.   logcall[0] = '\0';          /* initialize string       */
  1728.   if( loggedIn )
  1729.     {
  1730.     if (logBuf.lbflags.AIDE)
  1731.       {
  1732.       count++;
  1733.       strcat(logcall,"Aide, ");
  1734.       };
  1735.  
  1736.     if (logBuf.lbflags.NET_PRIVS)
  1737.       {
  1738.       count++;
  1739.       strcat(logcall,"NET, ");
  1740.       };
  1741.  
  1742.     if (logBuf.lbflags.DOOR_PRIVS)
  1743.       {
  1744.       count++;
  1745.       strcat(logcall,"Door, ");
  1746.       };
  1747.  
  1748.     if (logBuf.lbflags.DL_PRIVS)
  1749.       {
  1750.       count++;
  1751.       strcat(logcall,"File, ");
  1752.       };
  1753.  
  1754.     if (logBuf.lbflags.PERMANENT)
  1755.       {
  1756.       count++;
  1757.       strcat(logcall,"Permanent, ");
  1758.       };
  1759.  
  1760.     if (logBuf.lbflags.TWIT)
  1761.       {
  1762.       count++;
  1763.       logcall[0]='\0';
  1764.       strcat(logcall,"Full ");
  1765.       };
  1766.     };
  1767.   if( count == 0)strcpy( logcall, " No ");
  1768.   count = strlen(logcall);
  1769.   if( logcall[count-2] == ',')logcall[count-2] = '\0';
  1770.   return &logcall[0];
  1771.   }
  1772. /*
  1773. void Debug_space()
  1774.   {
  1775.   short i;
  1776.   for(i=0;i<level;i++)splitF(netLog," ");
  1777.   }
  1778. void Debug_Message(struct Message *Msg)
  1779.   {
  1780.   level++;
  1781.   Debug_space();splitF(netLog," struct Message:%08lX\n",Msg);
  1782.   level--;
  1783.   }
  1784. void Debug_Device( struct Device *Dev)
  1785.   {
  1786.   level++;
  1787.   Debug_space();splitF(netLog," struct Device:%08lX\n",Dev);  level--;
  1788.   }
  1789. void Debug_Unit(   struct Unit *Un)
  1790.   {
  1791.   level++;
  1792.   Debug_space();splitF(netLog," struct Unit :%08lX\n",Un);  level--;
  1793.   level--;
  1794.   }
  1795. int debug_count=0;
  1796. void DebugIoStdReq(struct IOStdReq *Std)
  1797.   {
  1798.   Debug_space();splitF(netLog,"struct IOStdReq:%08lX\n",Std);
  1799.   level++;
  1800.   Debug_Message(&Std->io_Message);
  1801.   Debug_Device( Std->io_Device);
  1802.   Debug_Unit(   Std->io_Unit);
  1803.   Debug_space();splitF(netLog,"io_Command:%04X\n",Std->io_Command);
  1804.   Debug_space();splitF(netLog,"  io_Flags:%02X\n",Std->io_Flags);
  1805.   Debug_space();splitF(netLog,"  io_Error:%02X\n",Std->io_Error);
  1806.   Debug_space();splitF(netLog," io_Actual:%08lX\n",Std->io_Actual);
  1807.   Debug_space();splitF(netLog," io_Length:%08lX\n",Std->io_Length);
  1808.   Debug_space();splitF(netLog,"   io_Data:%08lX\n",Std->io_Data);
  1809.   Debug_space();splitF(netLog," io_Offset:%08lX\n",Std->io_Offset);
  1810.   level--;
  1811.   }
  1812. void  DebugIoRequest (char * string,struct IOExtSer *iorequest)
  1813.   {
  1814.         int  mask = iorequest->io_SerFlags;
  1815.   if (!cfg.BoolFlags.debug)return;
  1816.   if( (debug_count++ % 1000 ) != 0 )return;
  1817.   Debug_space();splitF(netLog," %s=struct IOExtSer:%08lX\n",string,iorequest);
  1818.   DebugIoStdReq(&iorequest->IOSer);
  1819.   Debug_space();splitF(netLog,"CtlChar    0x%lx \n", iorequest->io_CtlChar);
  1820.   Debug_space();splitF(netLog,"RBufLen    %ld   \n", iorequest->io_RBufLen);
  1821.   Debug_space();splitF(netLog,"ExtFlags   0x%lx \n", iorequest->io_ExtFlags);
  1822.   Debug_space();splitF(netLog,"Baud       %ld   \n", iorequest->io_Baud);
  1823.   Debug_space();splitF(netLog,"BrkTime    %ld   \n", iorequest->io_BrkTime);
  1824.   Debug_space();splitF(netLog,"ReadLen    %ld   \n", iorequest->io_ReadLen);
  1825.   Debug_space();splitF(netLog,"WriteLen   %ld   \n", iorequest->io_WriteLen);
  1826.   Debug_space();splitF(netLog,"StopBits   %ld   \n", iorequest->io_StopBits);
  1827.   Debug_space();splitF(netLog,"SerFlags   0x%lx \n", iorequest->io_SerFlags);
  1828.         if (mask)
  1829.           {
  1830.     Debug_space();splitF(netLog,"           ");
  1831.                 if (mask & SERF_XDISABLED)  Debug_space();splitF(netLog,"XDISABLED ");
  1832.                 if (mask & SERF_EOFMODE)    Debug_space();splitF(netLog,"EOFMODE ");
  1833.                 if (mask & SERF_SHARED)     Debug_space();splitF(netLog,"SHARED ");
  1834.                 if (mask & SERF_RAD_BOOGIE) Debug_space();splitF(netLog,"RAD_BOOGIE ");
  1835.                 if (mask & SERF_QUEUEDBRK)  Debug_space();splitF(netLog,"QUEUEDBRK ");
  1836.                 if (mask & SERF_7WIRE)      Debug_space();splitF(netLog,"7WIRE ");
  1837.                 if (mask & SERF_PARTY_ODD)  Debug_space();splitF(netLog,"PARTY_ODD ");
  1838.                 if (mask & SERF_PARTY_ON)   Debug_space();splitF(netLog,"PARTY_ON");
  1839.     Debug_space();splitF(netLog,"\n");
  1840.           }
  1841.   Debug_space();splitF(netLog,"Status     0x%lx \n", iorequest->io_Status);
  1842.         return;
  1843. }
  1844. */
  1845.